const adminMapper = require('@/mappers/adminMapper');

const { transformPropertyNames, formatTime, handleTree, filterObjectByKeys} = require('@/utils/index.js');

/**
 * 映射字段 驼峰转下划线
 * 下划线转驼峰
 */
const propertyMap = {
    parent_id: 'parentId',
    dept_id: 'deptId',
    dept_name: 'deptName',
    create_time: 'createTime',
    order_num: 'orderNum',
    update_time: 'updateTime',
    create_by: 'createBy',
    post_code: 'postCode',
    post_id: 'postId',
    post_name: 'postName',
    post_sort: 'postSort',
    menu_id:'menuId',
    menu_name:'menuName',
    menu_type:'menuType',
    is_cache:'isCache',
    is_frame:'isFrame',
    role_key:'roleKey',
    role_id:'roleId',
    role_name:'roleName',
    role_sort:'roleSort',
    data_scope:'dataScope',
    menu_ids:'menuIds',
    dept_ids:'deptIds',
    dept_check_strictly:'deptCheckStrictly',
    menu_check_strictly:'menuCheckStrictly',
    dict_type:'dictType',
    dict_name:'dictName',
    dict_id:'dictId',
    dict_code: 'dictCode', 
    dict_sort: 'dictSort', 
    dict_label: 'dictLabel',
    dict_value: 'dictValue', 
    list_class:'listClass',
    config_id:'configId',
    config_name:'configName',
    config_key:'configKey',
    config_value:'configValue',
    config_type:'configType',

    notice_content:'noticeContent',
    notice_title:'noticeTitle',
    notice_type:'noticeType',
}
const reversePropertyMap = {};
for (const key in propertyMap) {
    reversePropertyMap[propertyMap[key]] = key;
}

// 处理数据结构，只保留 id、label 和 children 属性
function processTreeData(data) {
    return data.map(node => ({
        id: node.id,
        label: node.label,
        children: node.children ? processChildren(node.children) : []
    }));

    function processChildren(children) {
        return children.map(child => ({
            id: child.id,
            label: child.label,
            children: child.children ? processChildren(child.children) : []
        }));
    }
}
async function getDeptList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getDeptList(transReq);
    transResultData = transformPropertyNames(result, propertyMap);
    return transResultData 
}

async function addDept(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap);
    const result = await adminMapper.addDept(transReq);
    return result
}


async function getDept(payload) {
    const id = payload;
    const result = await adminMapper.getDept(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}

async function deptListExclude(payload) {
    const result = await adminMapper.deptListExclude(payload);
    transResultData = transformPropertyNames(result, propertyMap);
    return transResultData
}



async function updateDept(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateDept(transReq);
    return result
}


async function delDept(payload) {
    const id = payload;
    const result = await adminMapper.delDept(id);
    return result
}



async function getPostList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getPostList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData,total:result.total}
}



async function addPost(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.addPost(transReq);
    return result
}

async function getPost(payload) {
    const id = payload;
    const result = await adminMapper.getPost(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updatePost(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updatePost(transReq);
    return result
}


async function delPost(payload) {
    const id = payload;
    const result = await adminMapper.delPost(id);
    return result
}



async function getMenuList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getMenuList(transReq);
    transResultData = transformPropertyNames(result, propertyMap);
    return transResultData
}



async function addMenu(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.addMenu(transReq);
    return result
}

async function getMenu(payload) {
    const id = payload;
    const result = await adminMapper.getMenu(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updateMenu(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateMenu(transReq);
    return result
}


async function delMenu(payload) {
    const id = payload;
    const result = await adminMapper.delMenu(id);
    return result
}




async function getRoleList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getRoleList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    
    return {rows:transResultData,total:result.total}
}



async function addRole(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];

    const menu_ids = transReq.menu_ids;
    Reflect.deleteProperty(transReq, 'menu_ids');
    Reflect.deleteProperty(transReq, 'dept_ids');

    const result = await adminMapper.addRole(transReq);
    
    if(result.affectedRows){
        const role_id = result.insertId;
        let list = menu_ids.map(item => ({
            role_id,
            menu_id: item,
        }));
        await adminMapper.addRoleMenu(list)
    }

   
    return {}
}

async function getRole(payload) {
    const role_id = payload;
    const result = await adminMapper.getRole(role_id);
    result.menu_check_strictly = Boolean(result.menu_check_strictly);
    result.dept_check_strictly = Boolean(result.dept_check_strictly);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updateRoleStatus(payload) {
    payload.updateTime = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateRole(transReq);
    return result
}
async function updateRole(payload) {
    payload.updateTime = formatTime(Date.now());

    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateRole(transReq);

    const { role_id } = transReq;
    let exitMenus = await adminMapper.getRoleMenu({ role_id: role_id });
    exitMenus = exitMenus.map(item => item.menu_id);

    const { menuIds } = payload;
    // if (menuIds && menuIds.length > 0){
        console.log("xxxx1",menuIds)
        // 比较新旧数据
        const addMenus = menuIds.filter(id => !exitMenus.includes(id));
        const deletedMenus = exitMenus.filter(id => !menuIds.includes(id));

        console.log("新增了menu", addMenus);
        console.log("删除了menu", deletedMenus);
    // }
    


    // let exitDepts = await adminMapper.getRoleDept({ role_id: role_id });
    // exitDepts = exitDepts.map(item => item.dept_id);

    // const { deptIds } = payload;
    // if (deptIds && deptIds.length > 0){
    //     console.log("xxxx2",deptIds)
    //      // 比较新旧数据
    //     const addDepts = deptIds.filter(id => !exitDepts.includes(id));
    //     const deletedDepts = exitDepts.filter(id => !deptIds.includes(id));

    //     console.log("新增了dept", addDepts);
    //     console.log("删除了dept", deletedDepts);
    // }
   
    // 使用 Promise.all 确保所有操作同步完成
    await Promise.all([
        addMenus.length > 0 && adminMapper.addRoleMenu(addMenus.map(item => ({ role_id, menu_id: item }))),
        deletedMenus.length > 0 && adminMapper.deleteRoleMenu({ role_id: role_id, menu_ids: deletedMenus }),
        // addDepts.length > 0 && adminMapper.addRoleDept(addDepts.map(item => ({ role_id, dept_id: item }))),
        // deletedDepts.length > 0 && adminMapper.deleteRoleDept({ role_id: role_id, dept_ids: deletedDepts })
    ]);
    return result
}


async function delRole(payload) {
    const id = payload;
    const result = await adminMapper.delRole(id);
    return result
}


async function menuTreeSelect() {
    const result = await adminMapper.getMenuList({});
    
    transResultData = transformPropertyNames(result, propertyMap);
    transResultData.map((item,index)=>{
        item.id = item.menuId;
        item.label = item.menuName;
    })
    const data = handleTree(transResultData, "id");
    return processTreeData(data);
}


async function menuRoleMenuTreeselect(payload) {
    const { id } = payload;

    // 并发获取菜单列表和角色关联的菜单ID
    const [menuList, roleMenuIds] = await Promise.all([
      adminMapper.getMenuList({}),
      adminMapper.getRoleMenu({ role_id: id }),
    ]);
  
    // 转换菜单列表的属性名称
    const transResultData = transformPropertyNames(menuList, propertyMap);
    transResultData.forEach(item => {
      item.id = item.menuId;
      item.label = item.menuName;
    });
  
    // 处理角色关联的菜单ID
    const menuIds = roleMenuIds.map(item => item.menu_id);
  
    // 构建树形数据
    const data = handleTree(transResultData, "id");
  
    return {
      checkedKeys: menuIds,
      menus:  processTreeData(data),
    };
}


async function roleDeptTree(payload) {
    const { id } = payload;

    // 并发获取菜单列表和角色关联的菜单ID
    const [deptList, roleDeptIds] = await Promise.all([
      adminMapper.getDeptList({}),
      adminMapper.getRoleDept({ role_id: id }),
    ]);
  
    // 转换菜单列表的属性名称
    const transResultData = transformPropertyNames(deptList, propertyMap);
    transResultData.forEach(item => {
      item.id = item.deptId;
      item.label = item.deptName;
    });
  
    // 处理角色关联的菜单ID
    const dept_ids = roleDeptIds.map(item => item.dept_id);
    console.log("roleDeptIds",roleDeptIds,dept_ids)
    // 构建树形数据
    const data = handleTree(transResultData, "id");
  
    return {
      checkedKeys: dept_ids,
      depts:  processTreeData(data),
    };
}

async function roleDataScope(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    let exitDepts = await adminMapper.getRoleDept({ role_id: transReq.role_id });
    exitDepts = exitDepts.map(item => item.dept_id);

    const { deptIds } = payload;
    let result = adminMapper.updateRole(transReq);
    if (deptIds && deptIds.length > 0){
         // 比较新旧数据
        const addDepts = deptIds.filter(id => !exitDepts.includes(id));
        const deletedDepts = exitDepts.filter(id => !deptIds.includes(id));

        console.log("新增了dept", addDepts);
        console.log("删除了dept", deletedDepts);
        result = await Promise.all([
            addDepts.length > 0 && adminMapper.addRoleDept(addDepts.map(item => ({ role_id: transReq.role_id, dept_id: item }))),
            deletedDepts.length > 0 && adminMapper.deleteRoleDept({ role_id:  transReq.role_id, dept_ids: deletedDepts })
        ])
        return result
    }
    
}


async function roleAuthUserAllocatedListQuery(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getUserListAll(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData}
}

async function getUserList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getUserList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData,total:result.total}
}



async function addUser(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.addPost(transReq);
    return result
}

async function getUser(payload) {
    const id = payload;
    const result = await adminMapper.getUser(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updateUser(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateUser(transReq);
    return result
}


async function delUser(payload) {
    const id = payload;
    const result = await adminMapper.delUser(id);
    return result
}


async function getDictTypeList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getDictTypeList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData,total:result.total}
}


async function dictDataTypeQuery(payload) {
    const result = await adminMapper.dictDataTypeQuery(payload);
    transResultData = transformPropertyNames(result, propertyMap);
    return transResultData
}




async function addDictType(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.addDictType(transReq);
    return result
}

async function getDictType(payload) {
    const id = payload;
    const result = await adminMapper.getDictType(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updateDictType(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateDictType(transReq);
    return result
}


async function delDictType(payload) {
    const id = payload;
    const result = await adminMapper.delDictType(id);
    return result
}



async function getDictDataList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getDictDataList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData,total:result.total}
}



async function addDictData(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.addDictData(transReq);
    return result
}

async function getDictData(payload) {
    const id = payload;
    const result = await adminMapper.getDictData(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updateDictData(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateDictData(transReq);
    return result
}


async function delDictData(payload) {
    const id = payload;
    const result = await adminMapper.delDictData(id);
    return result
}



async function getconfigList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getconfigList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData,total:result.total}
}



async function addConfig(payload) {
    payload.create_time = formatTime(Date.now());
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.addConfig(transReq);
    return result
}

async function getConfig(payload) {
    const id = payload;
    const result = await adminMapper.getConfig(id);
    transResultData = transformPropertyNames([result], propertyMap);
    return transResultData[0]
}


async function updateConfig(payload) {
    payload.updateTime = formatTime(Date.now());
    payload.createTime = formatTime(payload.createTime);
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.updateConfig(transReq);
    return result
}


async function delConfig(payload) {
    const id = payload;
    const result = await adminMapper.delConfig(id);
    return result
}

async function getNoticeList(payload) {
    let transReq = transformPropertyNames([payload], reversePropertyMap)[0];
    const result = await adminMapper.getNoticeList(transReq);
    transResultData = transformPropertyNames(result.rows, propertyMap);
    return {rows:transResultData,total:result.total}
}


module.exports = { 
    getDeptList,
    addDept,
    getDept,
    deptListExclude,
    updateDept,
    delDept,

    getPostList,
    addPost,
    getPost,
    updatePost,
    delPost,

    getMenuList,
    addMenu,
    getMenu,
    updateMenu,
    delMenu,
    
    getRoleList,
    addRole,
    getRole,
    updateRole,
    updateRoleStatus,
    delRole,
    menuTreeSelect,
    menuRoleMenuTreeselect,
    roleDeptTree,
    roleDataScope,
    roleAuthUserAllocatedListQuery,


    getUserList,
    addUser,
    getUser,
    updateUser,
    delUser,

    getDictTypeList,
    dictDataTypeQuery,
    addDictType,
    getDictType,
    updateDictType,
    delDictType,


    getDictDataList,
    addDictData,
    getDictData,
    updateDictData,
    delDictData,


    getconfigList,
    addConfig,
    getConfig,
    updateConfig,
    delConfig, 



    getNoticeList
};